
/***
 * @Description:主要包括了整个系统的debug输出功能的实现，其中包括提示，告警，错误等功能的实现的C语言文件
 * @Author: Liverpool
 * @Date: 2024-02-11 15:21:20
 * @LastEditTime: 2024-02-11 15:45:10
 * @LastEditors: Liverpool
 */
#include "debug.h"
#include "ipaddr.h"
/***
 * @description:debug的调用打印输出信息函数
 * @Author: Liverpool
 * @Date: 2024-02-11 15:45:12
 * @return {*}
 * @param {int} module_level 模块定义的输出等级
 * @param {int} output_level 宏定义函数本身其定义的等级
 * @param {char} *file 需要打印输出信息的文件
 * @param {char} *fun 需要打印输出信息的函数
 * @param {int} line 在该文件中的代码行数位置
 * @param {char} *format 需要输出打印的格式化字符串
 * @param {char} ...  需要debug输出的格式化参数变量(可变参数)
 */
void debug_printf(int module_level, int output_level, const char *file, const char *fun, int line, const char *format, ...)
{
    // 引入信息等级制度所要输出的字体颜色样式
    static const char *title[] =
        {
            [D_DEBUG_Level_None] = "none",
            [D_DEBUG_Level_Error] = D_DEBUG_Style_Error "Error",
            [D_DEBUG_Level_Warning] = D_DEBUG_Style_Warning "Warning",
            [D_DEBUG_Level_Info] = "Info"};
    // 加入debug信息等级制度
    if (module_level < output_level)
        return;
        // file的结构文件分离，只保留最后的文件目录
#if D_DEBUG_DirectorySplit == 1
    const char *end = file + plat_strlen(file); // 得到文件目录字符串的结束位置
    while (end >= file)
    {
        if ((*end) == '\\' || (*end) == '/') // 从字符串从后往前找 找到最后的根文件
        {
            break;
        }
        end--;
    }
    end++;
    plat_printf("%s(%s-%s-%d):", title[output_level], end, fun, line);
#else
    char *token = NULL, *next_token = NULL, seps[] = "\\";
    char str_temp[128]; // 用于记录差分下来的字符串
    token = strtok_s((char *)file, seps, &next_token);
    plat_strcpy(str_temp, token);
    while (token)
    {
        plat_strcpy(str_temp, token);
        token = strtok_s(NULL, seps, &next_token);
    }
    plat_printf("(%s-%s-%d):", str_temp, fun, line);
#endif
    // 对需要打印的信息做格式化处理
    char buffer[128];
    va_list args;                        // 用于接收可变参数
    va_start(args, format);              // 接收可变参数赋值给args
    plat_vsprintf(buffer, format, args); // 对想要输出的信息进行格式化处理
    // plat_printf("%s\n", buffer);
    plat_printf("%s\n" D_DEBUG_Style_ReSet, buffer); // 重置控制台字体输出颜色
    va_end(args);                                    // 释放可变参数资源
}

/***
 * @description: 打印输出网络接口的硬件mac地址
 * @Author: Liverpool
 * @Date: 2024-05-07 01:39:05
 * @return {*}
 * @param {char} *msg  需要打印的ms描述信息
 * @param {uint8_t} *hwaddr 需要打印的硬件地址
 * @param {int} len 硬件地址的长度
 */
void debug_dump_hwaddr(const char *msg, const uint8_t *hwaddr, int len)
{
    if (msg)
    {
        plat_printf("%s ", msg);
    }
    if (len)
    {
        for (int i = 0; i < len; i++)
        {
            plat_printf("%02x-", hwaddr[i]);
        }
    }
    else
    {
        plat_printf("%s ", "none");
    }
}

/***
 * @description: 打印输出网络接口的点分十进制的IP地址
 * @Author: Liverpool
 * @Date: 2024-05-07 01:40:34
 * @return {*}
 * @param {char} *msg 需要输出打印的描述信息
 * @param {D_IP_ADDR} *ipaddr 需要打印的IP地址的内存地址
 */
void debug_dump_ipaddr(const char *msg, const struct ip_addr *ipaddr)
{
    if (msg)
    {
        plat_printf("%s ", msg);
    }
    if (ipaddr)
    {
        plat_printf("%d.%d.%d.%d", ipaddr->a_addr[0], ipaddr->a_addr[1], ipaddr->a_addr[2], ipaddr->a_addr[3]);
    }
    else
    {
        plat_printf("0.0.0.0");
    }
}

/***
 * @description: 打印输出网络接口的点分十进制的IP地址,从uiint8的buf数组中打印
 * @Author: Liverpool
 * @Date: 2024-05-07 01:40:34
 * @return {*}
 * @param {char} *msg 需要输出打印的描述信息
 * @param {uint8_t} *ipaddr 需要打印的IP地址的内存地址
 */
void debug_dump_ipaddr_buf(const char *msg, const uint8_t *ipaddr)
{
    if (msg)
    {
        plat_printf("%s ", msg);
    }
    if (ipaddr)
    {
        plat_printf("%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
    }
    else
    {
        plat_printf("0.0.0.0");
    }
}